//
// Created by dell on 2023/12/14.
//

#ifndef WIN_DEMO_DATABASE_H
#define WIN_DEMO_DATABASE_H

#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <algorithm>
#include "file_parse.h"
#include "headers/encrypt/xorencrypt.h"


// 数据库数据
static std::map<std::string, std::string> db;

namespace DB {

    /**
     * 获取当前的数据存放目录
     * @return
     */
    static std::string getCurrentPath() {
        char work_path[100];
        std::string db_file = "/data.json";
        std::string db_path = "/db";
        std::string default_db_file = "c:/" + db_path;
        std::string path;
        if (getcwd(work_path, sizeof(work_path)) != nullptr) {
            path = std::string(work_path).append(db_path);
        } else {
            // 使用默认目录, c:/
            path.append(default_db_file);
        }
        std::replace(path.begin(), path.end(), '\\', '/');
        printf("current db path: %s \n", path.c_str());

        struct stat filestat;
        // 文件不存在
        if (stat(path.c_str(), &filestat) == -1) {
            // 目录不存在则创建
            mkdir(path.c_str());
        }
        // O_RDWR: 以读写方式打开 O_CREAT: 若文件不存在,则创建
        int fd = open(path.append(db_file).c_str(), O_RDWR | O_CREAT, 0777);
        return fd == -1 ? "" : path;
    }

    // 数据存放目录
    static std::string path = getCurrentPath();

    // 初始化数据, 读取文件到内存
    void init_data() {
        // 这里测试线定义好文件位置, 后面看能不能定义到外部, 进行动态读取
        std::map<std::string, std::string> data = IOUtils::readFile(path);
        // 读取数据, 对密码进行解密
        for (const auto &item: data) {
            std::string username = item.first;
            std::string password = item.second;
            printf("初始化读取数据-> user_name: %s\n", username.c_str());
            db.insert(std::pair<std::string, std::string>(username, password));
        }
    }

    /**
     * 刷新数据
     */
    void refresh_database() {
        init_data();
    }

    /**
     * 数据入库
     * @param data 数据
     * @return
     */
    int insert(std::map<std::string, std::string> data) {
        std::map<std::string, std::string> insert_data;
        if (!data.empty()) {
            for (const auto &item: data) {
                std::string username = item.first;
                std::string password = item.second;
                insert_data.insert(std::pair<std::string, std::string>(username, password));
            }
        }
        IOUtils::wriedFile(path, insert_data);
        return 0;
    }


}

#endif //WIN_DEMO_DATABASE_H
